﻿namespace LxCFD
{
    public struct MeshCalculator
    {

    }
    public struct FvCell
    {
        //拓扑关系
        public int[] OFaces;
        public int[] NFaces;
        //几何信息，内部
        public Vector3d Center;//对于边界，等于边界面的中心
        public double Volumn;//对于边界，等于边界面的面积，

        public MatrixToCalGrad_LeastSquare_LengthWeighted MatrixToCalGrad;
        public void CalGeometry_inner(FvFace[] faces)
        {
            Vector3d Center = new Vector3d();//先重置为0，后期全部改为vector3d类型
            Volumn = 0;//先重置为0
            foreach (int fid in OFaces)
            {
                ref FvFace face = ref faces[fid];
                double volWeight = Vector3d.DotProduct(face.Center, face.Normal);
                Center.AddToSelf(volWeight * face.Center);
                Volumn += volWeight;
            }
            foreach (int fid in NFaces)
            {
                ref FvFace face = ref faces[fid];
                double volWeight = -Vector3d.DotProduct(face.Center, face.Normal);//多一负号
                Center.AddToSelf(volWeight * face.Center);
                Volumn += volWeight;
            }
            if (Volumn <= 0)
            {
                LxConsole.Error( "发现体积小于等于0的网格，会导致计算出错");
            }
            else
            {
                Center.MultiplyToSelf(0.75 / Volumn);
                this.Center = Center;
                Volumn /= 3.0;
            }
        }
        public void CalGeometry_bound(FvFace[] faces)
        {
            ref FvFace face = ref faces[NFaces[0]];
            Center = face.Center;
            Volumn = face.Area;
        }
        public void CalMatrix_LeastSquare(FvFace[] faces)
        {
            MatrixToCalGrad = new MatrixToCalGrad_LeastSquare_LengthWeighted();
            foreach (int fid in OFaces)
            {
                MatrixToCalGrad.AddVector_FromThisToAdjacent(faces[fid].OToN);
            }
            foreach (int fid in NFaces)
            {
                MatrixToCalGrad.AddVector_FromThisToAdjacent(-faces[fid].OToN);
            }
            MatrixToCalGrad.Inverse();
        }
        public Vector3d CalGradient_LeastSquare(FvFace[] faces, double[] phi)
        {
            Vector3d v3d = new Vector3d();
            foreach (int faceIndex in OFaces)
            {
                v3d.AddToSelf(faces[faceIndex].CalONGradient_DistanceWeighted(phi));
            }
            foreach (int faceIndex in NFaces)
            {
                v3d.AddToSelf(faces[faceIndex].CalONGradient_DistanceWeighted(phi));
            }
            return MatrixToCalGrad.CalGradPhi(v3d);
        }
        public double CalIfOwnerAddElseMunus(double[] faceDataArray)
        {
            double result = 0;
            foreach (int faceIndex in OFaces)
            {
                result += faceDataArray[faceIndex];
            }
            foreach (int faceIndex in NFaces)
            {
                result -= faceDataArray[faceIndex];
            }
            return result;
        }
        public double CalAllAdd(double[] faceDataArray)
        {
            double result = 0;
            foreach (int faceIndex in OFaces)
            {
                result += faceDataArray[faceIndex];
            }
            foreach (int faceIndex in NFaces)
            {
                result += faceDataArray[faceIndex];
            }
            return result;
        }
        public double CalAllAdd(double[] Oface, double[] Nface)
        {
            double result = 0;
            foreach (int faceIndex in OFaces)
            {
                result += Oface[faceIndex];
            }
            foreach (int faceIndex in NFaces)
            {
                result += Nface[faceIndex];
            }
            return result;
        }

    }
}
